/**
 * @file ThreadObj.h
 * @author huangxiaozhu (xiaozhuhuang2014@163.com)
 * @brief  线程对象，方便对线程的使用
 * @version 1.0.0
 * @date 2024-02-26
 * 
 * @copyright Copyright (c) 2024
 * 
 */

#pragma once

#include <thread>
#include <string>
#include <atomic>
#include <mutex>
#include <condition_variable>

#include "ThreadCond.h"

enum DoTaskStatus{
    DOTASK_IDEL = 0,
    DOTASK_SUCCESS,
    DOTASK_FAILURE,
    DOTASK_RUNNING
};

const int WAIT_FOR_INFINED = -1;                            // 无限等待
const std::string THREAD_DEFAULT_NAME = "hxzTh";            // 默认的线程名字

class ThreadObj
{
public:
    explicit ThreadObj(const std::string &thName = THREAD_DEFAULT_NAME);
    virtual ~ThreadObj();

    void SetDoTaskStatus(DoTaskStatus newStatus);
    DoTaskStatus GetDoTaskStatus();
    
    bool IsThreadCreated();
    void SetIsThreadCreated(bool isThreadCreated);

    bool IsRunning();
    bool CanHandleNewTask();
    
public: 
    void ThreadFunc();
    bool CreateThread();
    void DestroyThread();

    virtual int StartTask();
    virtual bool WaitTaskFinished(DoTaskStatus& status, int ms = WAIT_FOR_INFINED);

public:
    void SleepS(int second);
    void SleepMS(int ms);
    void SleepUS(int us);

protected:
    virtual int DoTask() = 0;                                   // 真正执行任务的函数。
    virtual int PreDoTask(){return 0;}                          // 任务的前置工作
    virtual void PosDoTask(){}                                  // 任务的后置工作
    virtual int DoAfterTaskFinished(){return 0;}                // 任务结束后的处理动作。接口函数，为子类提供任务完成后的回调接口。

    virtual void PreClearForStopThread(){}                      // 结束线程之前的清理动作


    /**
     * @brief 任务线程状态切换的处理回调函数。
     *        注意，此函数不能进行耗时处理动作。
     * 
     * @param preStatus 
     * @param toStatus 
     */
    virtual void StatusChangedHandle(const DoTaskStatus& preStatus, 
                                     const DoTaskStatus& toStatus){}
    void ResetCondsVariable();

    void ResetThreadState();

private:
    std::thread m_thread;
    std::string m_thName = THREAD_DEFAULT_NAME;
    DoTaskStatus m_doTaskStatus{DoTaskStatus::DOTASK_IDEL};

    std::atomic<bool> m_isThreadCreated{false};
    bool m_stop{false};

    ThreadCond m_condDoTask;                                    // 线程的执行的等待的条件变量

    ThreadCond m_condNotifyCreate;                              // 通知线程创建完成
    ThreadCond m_condNotifyStart;                               // 通知任务已经开始
    ThreadCond m_condNotifyEnd;                                 // 外部接口需要等待任务执行结束的接口的返回
};

